<template>
    <div class="handle_container" style="padding-top: 16px">
        <el-button round type="primary" @click="newAdmin">新增管理员</el-button>
    </div>
    <div class="table_container">
        <el-table
            :cell-style="{ fontSize: '14px', color: '#333333' }"
            :data="adminPage.records"
            :header-cell-style="{ background: '#F7F8FA' }"
            :header-row-style="{ fontSize: '14px', color: '#333', height: '48px' }"
            style="max-height: calc(100vh - 246px)"
        >
            <template #empty>
                <ElTableEmpty />
            </template>
            <el-table-column align="left" label="昵称" prop="nickname"></el-table-column>
            <el-table-column align="left" label="角色名称" prop="userRole.role.name"></el-table-column>
            <el-table-column align="left" label="电话" prop="mobile"></el-table-column>
            <el-table-column align="left" label="邮箱" prop="email"></el-table-column>
            <el-table-column align="left" label="创建时间" prop="createTime" />
            <el-table-column align="left" label="状态">
                <template #default="scope">
                    <el-switch v-model="scope.row.userRole.enable" :loading="scope.row.loading" @change="changeAdminStatus(scope.row)" />
                </template>
            </el-table-column>
            <el-table-column align="right" fixed="right" label="操作" width="90px">
                <template #default="scope">
                    <el-link type="primary" @click="editAdmin(scope.row)">编辑</el-link>&nbsp;
                    <el-popconfirm
                        v-if="!scope.row.userRole.enable"
                        cancel-button-text="取消"
                        confirm-button-text="确定"
                        title="确定删除这个角色吗?"
                        @confirm="deleteData(scope.row.id)"
                    >
                        <template #reference>
                            <el-link style="color: red" type="primary">删除</el-link>
                        </template>
                    </el-popconfirm>
                </template>
            </el-table-column>
        </el-table>
    </div>

    <BetterPageManage
        :page-num="adminPage.page.current"
        :page-size="adminPage.page.size"
        :total="adminPage.total"
        load-init
        @reload="reload"
        @handle-current-change="handleCurrentChange"
        @handle-size-change="handleSizeChange"
    />

    <el-dialog v-model="adminPage.showDialog" title="自定义管理员" width="500px">
        <el-form ref="formRef" :model="adminPage.form" :rules="adminPage.rules" label-width="80px">
            <el-form-item label="角色" prop="roleId">
                <el-select v-model="adminPage.form.roleId" clearable placeholder="请选择" style="width: 90%">
                    <el-option v-for="role in adminPage.roles" :key="role.id" :label="role.name" :value="role.id" />
                </el-select>
                <el-link :icon="Refresh" title="刷新" @click="reloadRoles" />
            </el-form-item>
            <el-form-item label="昵称" prop="nickname">
                <el-input v-model="adminPage.form.nickname" :clearable="true" maxlength="20" />
            </el-form-item>
            <el-form-item :label="selectedUser.selected ? '用户' : '用户名'" prop="username">
                <el-autocomplete
                    v-model="adminPage.form.username"
                    :debounce="850"
                    :fetch-suggestions="queryUserByKeywords"
                    :maxlength="11"
                    :teleported="false"
                    :trigger-on-focus="false"
                    clearable
                    hide-loading
                    style="width: 100%"
                    @clear="clearSelectUser"
                    @input="usernameChange"
                    @select="selectUser"
                >
                    <template #default="{ item }">
                        <div>{{ item.username || item.mobile || item.email || item.userId }}</div>
                    </template>
                </el-autocomplete>
                <div class="select-user-tips">
                    <el-descriptions v-show="selectedUser.selected" :column="2" border size="small">
                        <el-descriptions-item>
                            <template #label>用户</template>
                            <el-avatar :icon="User" :src="selectedUser.avatar" />
                            <br />{{ selectedUser.username }} <br />{{ selectedUser.nickname }}
                        </el-descriptions-item>
                        <el-descriptions-item v-if="selectedUser.mobile || selectedUser.email">
                            <template #label>联系</template>
                            {{ selectedUser.mobile }}
                            <br />{{ selectedUser.email }}
                        </el-descriptions-item>
                    </el-descriptions>
                </div>
            </el-form-item>
            <el-form-item v-if="!selectedUser.selected" label="密码" prop="password">
                <el-input v-model="adminPage.form.password" autocomplete="new-password" clearable maxlength="20" show-password type="password" />
            </el-form-item>
            <el-form-item v-if="!selectedUser.selected" label="确认密码" prop="confirmPassword">
                <el-input v-model="adminPage.form.confirmPassword" clearable maxlength="20" show-password type="password" />
            </el-form-item>
            <el-form-item autocomplete="new-email" label="邮箱" prop="email">
                <el-input v-model="adminPage.form.email" clearable maxlength="20" />
            </el-form-item>
            <el-form-item autocomplete="new-mobile" label="联系电话" prop="mobile">
                <el-input v-if="!selectedUser.selected" v-model="adminPage.form.mobile" clearable maxlength="20" />
                <template v-else>{{ selectedUser.mobile }}</template>
            </el-form-item>
        </el-form>
        <template #footer>
            <span>
                <el-button @click="handleClose">取消</el-button>
                <el-button type="primary" @click="saveData">保存</el-button>
            </span>
        </template>
    </el-dialog>
</template>

<script lang="ts" setup>
import BetterPageManage from '@/components/BetterPageManage/BetterPageManage.vue'
import type { FormInstance, FormRules } from 'element-plus'
import { ElMessage } from 'element-plus'
import { Refresh, User } from '@element-plus/icons-vue'
import {
    deleteShopAdmin,
    enableDisableShopCustomAdmin,
    getAdminPage,
    getAdminRegisterDataById,
    getAvailableUser,
    getRolePage,
    newShopCustomAdmin,
    updateShopCustomAdmin,
} from '@/apis/perm'

const defaultForm = {
    roleId: null,
    userId: null,
    nickname: null,
    username: null,
    password: null,
    confirmPassword: null,
    mobile: null,
    email: null,
}
const defaultSelectedUser = {
    selected: false,
    userId: null,
    username: null,
    mobile: null,
    email: null,
    avatar: null,
    nickname: null,
}
const passwordPattern = '(?![A-Z]+$)(?![a-z]+$)(?!\\d+$)(?![\\W_]+$)\\S{6,20}'
const formRef = ref<FormInstance | null>(null)
const selectedUser = ref({ ...defaultSelectedUser })
const autocompleteDisabled = ref(false)
const adminPage = reactive<any>({
    queryUsers: [],
    selectedId: null,
    form: { ...defaultForm },
    rules: {
        roleId: [{ required: true, message: '请选择用户角色', trigger: 'change' }],
        nickname: [
            { required: true, message: '请输入用户昵称' },
            { min: 1, max: 20, message: '昵称限制在1-20个字符之间' },
        ],
        username: [
            { required: true, message: '用户名需包含两类：大写字母、小写字母、数字、特殊字符', trigger: 'blur' },
            {
                validator(rule, value, callback) {
                    if (selectedUser.value.selected) {
                        return callback()
                    }
                    if (!value) {
                        return callback(new Error('用户名需包含两类：大写字母、小写字母、数字、特殊字符'))
                    }
                    if (value.length > 11) {
                        return callback(new Error('用户名长度限定在11个字符'))
                    }
                    if (new RegExp(passwordPattern).test(value)) {
                        return callback()
                    }
                    return callback('用户名需包含两类：大写字母、小写字母、数字、特殊字符')
                },
            },
        ],
        userId: [{ required: true, message: '请输入用户名或选择对应的用户', trigger: 'blur' }],
        password: [
            { required: true, message: '请输入密码' },
            { min: 6, max: 20, message: '长度限制在6-20个字符之间' },
            { pattern: passwordPattern, message: '密码需要在大写字母、小写字母、数字、字符之间任选其二' },
        ],
        confirmPassword: [
            { required: true, message: '请输入确认密码' },
            { min: 6, max: 20, message: '长度限制在6-20个字符之间' },
            { pattern: passwordPattern, message: '密码需要在大写字母、小写字母、数字、特殊字符之间任选其二' },
            {
                validator: (rule, value, callback) => {
                    if (adminPage.form.confirmPassword !== adminPage.form.password) {
                        callback(new Error('确认密码和密码不一致'))
                        return
                    }
                    callback()
                },
                trigger: 'blur',
            },
        ],
        email: [
            // { required: true, message: '请输入用户邮箱地址' },
            { type: 'email', message: '请输入正确的邮箱地址' },
        ],
        mobile: [
            { required: true, message: '请输入用户手机号', trigger: 'blur' },
            {
                pattern: '((?:0|86|\\+86)?1[3-9]\\d{9})|((010|02\\d|0[3-9]\\d{2})-?(\\d{6,8}))',
                message: '请输入正确的手机号',
            },
        ],
    } as FormRules,
    roles: [],
    showDialog: false,
    records: [],
    total: 0,
    page: { size: 10, current: 1 },
})
watch(
    () => selectedUser.value.selected,
    (value) => {
        adminPage.rules.mobile[0].required = !value
    },
)
onMounted(() => {
    reload()
})
const newAdmin = async () => {
    await reloadRoles()
    adminPage.showDialog = true
    adminPage.selectedId = null
    adminPage.form = { ...defaultForm }
    selectedUser.value = { ...defaultSelectedUser }
}
const usernameChange = () => {
    if (selectedUser.value.selected) {
        clearSelectUser()
    }
}
const reload = () => {
    getAdminPage({ ...adminPage.page }).then((response) => {
        const data = response.data
        adminPage.records = data.records
        adminPage.total = data.total
    })
}
const hideDialogAndReload = () => {
    adminPage.showDialog = false
    reload()
}
const saveData = () => {
    formRef.value?.validate(async (valid) => {
        if (!valid) {
            return
        }
        const selectedId = adminPage.selectedId
        const form = markRaw(adminPage.form)
        if (selectedUser.value.selected) {
            form.username = null
        }
        if (!selectedId) {
            const { code, data, msg } = await newShopCustomAdmin(form)
            if (code !== 200) {
                ElMessage.error(msg ? msg : '保存失败')
                return
            }
            ElMessage.success('已保存')
            hideDialogAndReload()
            return
        }
        const { code, data, msg } = await updateShopCustomAdmin(selectedId, form)
        if (code !== 200) {
            ElMessage.error(msg ? msg : '保存失败')
            return
        }
        ElMessage.success('已保存')
        hideDialogAndReload()
    })
}
const queryUserByKeywords = async (keywords: string, cb: (arg: any) => void) => {
    if (!keywords) {
        autocompleteDisabled.value = true
        cb([])
        return
    }
    const { code, data } = await getAvailableUser(keywords)
    autocompleteDisabled.value = !data.records.length
    cb(data.records)
}
const selectUser = (data: { userId: any; username: any; mobile: any; email: any; avatar: any; nickname: any; id: any }) => {
    if (!data) {
        selectedUser.value.selected = false
        return
    }
    const { userId, username, mobile, email, avatar, nickname, id } = data
    selectedUser.value = { selected: true, userId: id, username, mobile, email, avatar, nickname }
    adminPage.form.username = nickname || username
    adminPage.form.userId = userId
}
const clearSelectUser = () => {
    adminPage.form.userId = null
    adminPage.form.username = null
    selectedUser.value = { ...defaultSelectedUser }
}
const reloadRoles = () => {
    getRolePage({
        current: 1,
        size: 200,
    }).then((response) => {
        adminPage.roles = response.data.records || []
    })
}
const editAdmin = (row: any) => {
    const userId = row.userRole.user.id
    if (adminPage.roles.length === 0) {
        reloadRoles()
    }
    getAdminRegisterDataById(userId).then(async (response) => {
        const data = response.data
        if (!data) {
            return
        }
        adminPage.selectedId = row.id
        adminPage.form = {
            roleId: row.userRole.role.id,
            userId: userId,
            nickname: row.nickname,
            username: data.nickname,
            password: null,
            confirmPassword: null,
            mobile: row.mobile,
            email: row.email,
        }
        selectUser({ ...row, ...data })
        adminPage.showDialog = true
    })
}
const changeAdminStatus = async (row: { loading: boolean; id: any; userRole: { enable: any; id: string } }) => {
    row.loading = true
    const { code, msg } = await enableDisableShopCustomAdmin(row.id, row.userRole.enable)
    if (code === 200) {
        ElMessage.success('已更改')
        row.loading = false
    } else {
        ElMessage.error(msg)
        row.loading = false
    }
    reload()
}
const deleteData = (dataId: string) => {
    deleteShopAdmin(dataId).then((res) => {
        if (res.code !== 200) {
            ElMessage.error(res.msg || '删除失败')
            return
        }

        ElMessage.success('已删除')
        hideDialogAndReload()
    })
}
const handleClose = () => {
    formRef.value?.clearValidate()
    adminPage.showDialog = false
}
const handleCurrentChange = (current: number) => {
    adminPage.page.current = current
    reload()
}
const handleSizeChange = (size: number) => {
    adminPage.page.size = size
    reload()
}
</script>

<style lang="scss" scoped>
.select-user-tips {
    font-size: 12px !important;
    color: $rows-text-color-grey;
}

.select-user-tips .new-user {
    color: #b67c03;
}
</style>
